iT邦幫忙

2026 iThome 鐵人賽

DAY 2
0
Claude AI

Claude Code陪跑:一人開發者的訂閱制SaaS架構與十大地雷實戰記系列 第 2

# Day 2|技術選型:本機/正式站雙資料庫 fallback 的設計理由

  • 分享至 

  • xImage
  •  

一個違反直覺的決定

教科書會告訴你:開發環境要盡量貼近正式環境,資料庫當然要用同一種。我反著做——本機開發用 DuckDB,正式站用雲端代管的 Postgres——而且是刻意的。

理由要從「一人維運」的成本結構講起。

本機要的是「零摩擦」

DuckDB 是嵌入式資料庫,一個檔案就是一個資料庫。這帶來的開發體驗差異是量級的:

  • 不用裝資料庫伺服器、不用管連線埠、不用設帳號密碼
  • 測試想要乾淨環境?換個檔案路徑就是全新資料庫
  • 想比對兩份資料狀態?複製檔案就好
  • clone 專案下來 pytest 直接能跑,零設定

對只有一個人的團隊,每一分鐘的環境摩擦都是從開發時間裡扣的。「跟正式環境一致」的好處是真的,但它的前提是你有力氣養一個本機的 Postgres——我選擇把這份力氣省下來,用別的方式補回一致性的缺口(後面會講代價)。

正式站要的是「別讓我操心」

正式站的考量完全相反:要備份、要承受真實連線、掛了要能救。雲端代管的 Postgres 把這些全包了。一人團隊最貴的資源是注意力,正式站資料庫是最不該佔用注意力的地方。

中間那層怎麼接

關鍵在連線層的抽象。專案裡有一個 db.py,所有資料庫操作都走它,大概是這個形狀:

def get_conn():
    url = os.environ.get("DATABASE_URL")
    if url:
        return _pg_pool.getconn()      # 正式站:Postgres 連線池
    return duckdb.connect(_LOCAL_PATH)  # 本機/CI:DuckDB 檔案

沒有 DATABASE_URL 就自動退回本機模式——這不是防呆,是刻意設計的 fallback。CI 環境、雲端沙箱、任何一個新的工作階段(包含 AI agent 開的),都不需要正式站的連線資訊就能跑完整套測試。這件事對 AI 協作特別重要:agent 可以放心大膽地跑測試、做實驗,因為它碰到的永遠是本機資料庫,物理上摸不到正式資料。

這個設計的代價(誠實揭露)

兩種資料庫的 SQL 方言不完全相同,這是這個架構的原罪,具體要付的帳:

  1. 參數佔位符不同:連線層要做一層 SQL 轉換
  2. 某些型別寫法不同:本機接受的寫法,正式站可能直接報錯
  3. 最危險的:本機全綠不等於正式站不炸——有一整類 bug 只在正式站的驅動程式解析階段引爆

第三點就是明天要講的地雷 #1,是整份地雷清單裡最陰險的一條:所有測試都過了,部署出去,炸了。

給要做同樣選擇的人

這個架構值不值得抄,取決於一個問題:你的測試量夠不夠大、跑得夠不夠勤? 我的 1200+ 個測試是這個架構的安全網——方言差異造成的問題,靠測試數量跟 CI 關卡去攔(Day 27 細講部署驗證)。如果你的專案測試稀疏,雙資料庫的裂縫會直接漏到正式站,那還是乖乖用同一種資料庫比較安全。


上一篇
# Day 1|破題:一個人維運商業服務,Claude Code 扮演的角色到底是什麼
下一篇
# Day 3|CLAUDE.md 是什麼?把地雷清單寫給 AI 讀,不是寫給自己看
系列文
Claude Code陪跑:一人開發者的訂閱制SaaS架構與十大地雷實戰記4
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言